
#include "lcd_internal.h"

#if !MODULE_CHECK_ENABLED( LCD_QSPI )
#error "must define qspi lcd interface!!!"
#endif


GUI_RAM_CODE
bool lcd_write_completed(void)
{
    if( lcd_wrctl.block_write ) 
    {
        if( lcd_wrctl.offset < lcd_wrctl.size )
        {
            uint16_t remain = lcd_wrctl.size - lcd_wrctl.offset;
            if( remain > LCD_XFER_MAX_SIZE )
            {
                remain = LCD_XFER_MAX_SIZE;
            }
            LCD_SEND_DATA_ASYNC( lcd_wrctl.pdata + lcd_wrctl.offset, remain );
            lcd_wrctl.offset += remain;
        }
        else 
        {
            lcd_wrctl.blocks.used ++;
            if( lcd_wrctl.blocks.used < lcd_wrctl.blocks.count )
            {
                // check next row 
                lcd_wrctl.pdata += lcd_wrctl.blocks.offset; // next block  
                lcd_wrctl.offset = 0; 
                uint16_t remain = lcd_wrctl.size;
                if( remain > LCD_XFER_MAX_SIZE )
                {
                    remain = LCD_XFER_MAX_SIZE; 
                }
                
                LCD_SEND_DATA_ASYNC( lcd_wrctl.pdata, remain );
                lcd_wrctl.offset = remain; //start a block 
            }
            else 
            {
                lcd_wrctl.isbusy = false; 
            }
        }
    }
    else 
    {
        if( lcd_wrctl.offset < lcd_wrctl.size )
        {
            uint16_t remain = lcd_wrctl.size - lcd_wrctl.offset;
            if( remain > LCD_XFER_MAX_SIZE )
            {
                remain = LCD_XFER_MAX_SIZE;
            }
            LCD_SEND_DATA_ASYNC( lcd_wrctl.pdata + lcd_wrctl.offset, remain );
            lcd_wrctl.offset += remain;
        }
        else 
        {
            lcd_wrctl.isbusy = false; 
        }
    }
    return lcd_wrctl.isbusy;
}



static void driver_init(void)
{
    LCD_SET_nRESET;
    LCD_DELAY_MS( 10 );
    LCD_SET_RESET;
    LCD_DELAY_MS( 10 );
    LCD_SET_nRESET;
    LCD_DELAY_MS( 120 );
	LOG0("[QSPI reset] driver_init");

#if 1// normal, ST77916_BOE

    {
        uint8_t data[] = {0x28}; 
        lcd_qspi_write_cmd_para( 0xF0 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x28};
        lcd_qspi_write_cmd_para( 0xF2 , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0xF0}; 
        lcd_qspi_write_cmd_para( 0x73 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xD1}; 
        lcd_qspi_write_cmd_para( 0x7C , data, sizeof(data) );
    }
   {
        uint8_t data[] = {0xE0};
        lcd_qspi_write_cmd_para( 0x83 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x61};
        lcd_qspi_write_cmd_para( 0x84 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xF2}; 
        lcd_qspi_write_cmd_para( 0x82 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00};
        lcd_qspi_write_cmd_para( 0xF0 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x01}; 
        lcd_qspi_write_cmd_para( 0xF1 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x40};
        lcd_qspi_write_cmd_para( 0xB0 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x33}; 
        lcd_qspi_write_cmd_para( 0xB1 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x26};
        lcd_qspi_write_cmd_para( 0xB2 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x66}; 
        lcd_qspi_write_cmd_para( 0xB4 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x44};
        lcd_qspi_write_cmd_para( 0xB5 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xA5}; 
        lcd_qspi_write_cmd_para( 0xB6 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x40};
        lcd_qspi_write_cmd_para( 0xB7 , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x8C};
        lcd_qspi_write_cmd_para( 0xB8 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xBA , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x08};
        lcd_qspi_write_cmd_para( 0xBB , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x08}; 
        lcd_qspi_write_cmd_para( 0xBC , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00};
        lcd_qspi_write_cmd_para( 0xBD , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x80}; 
        lcd_qspi_write_cmd_para( 0xC0 , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x10}; 
        lcd_qspi_write_cmd_para( 0xC1 , data, sizeof(data) );
    }
   {
        uint8_t data[] = {0x37}; 
        lcd_qspi_write_cmd_para( 0xC2 , data, sizeof(data) );
    }
  {
        uint8_t data[] = {0x80}; 
        lcd_qspi_write_cmd_para( 0xC3 , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x10}; 
        lcd_qspi_write_cmd_para( 0xC4 , data, sizeof(data) );
    }
   {
        uint8_t data[] = {0x37}; 
        lcd_qspi_write_cmd_para( 0xC5 , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0xA9}; 
        lcd_qspi_write_cmd_para( 0xC6 , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x41}; 
        lcd_qspi_write_cmd_para( 0xC7 , data, sizeof(data) );
    }
   {
        uint8_t data[] = {0x01}; 
        lcd_qspi_write_cmd_para( 0xC8 , data, sizeof(data) );
    }
   {
        uint8_t data[] = {0xA9}; 
        lcd_qspi_write_cmd_para( 0xC9 , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x41}; 
        lcd_qspi_write_cmd_para( 0xCA , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x01}; 
        lcd_qspi_write_cmd_para( 0xCB , data, sizeof(data) );
    }
   {
        uint8_t data[] = {0x91}; 
        lcd_qspi_write_cmd_para( 0xD0 , data, sizeof(data) );
    }
	
   {
        uint8_t data[] = {0x68}; 
        lcd_qspi_write_cmd_para( 0xD1 , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x68}; 
        lcd_qspi_write_cmd_para( 0xD2 , data, sizeof(data) );
    }
   {
        uint8_t data[] = {0x00,0xA5}; 
        lcd_qspi_write_cmd_para( 0xF5 , data, sizeof(data) );
    }
   {
        uint8_t data[] = {0x10}; 
        lcd_qspi_write_cmd_para( 0xF1 , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xF0 , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para( 0xF0 , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0xF0,0x06,0x0B,0x09,0x09,0x16,0x32,0x44,0x4A,0x37,0x13,0x13,0x2E,0x34}; 
        lcd_qspi_write_cmd_para( 0xE0 , data, sizeof(data) );
    }
 

	
    {
        uint8_t data[] = {0xF0,0x06,0x0B,0x09,0x08,0x05,0x32,0x33,0x49,0x17,0x13,0x13,0x2E,0x34}; 
        lcd_qspi_write_cmd_para( 0xE1 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x10}; 
        lcd_qspi_write_cmd_para( 0xF0  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x10}; 
        lcd_qspi_write_cmd_para( 0xF3  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0A}; 
        lcd_qspi_write_cmd_para( 0xE0  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xE1  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xE2  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xE3  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xE0}; 
        lcd_qspi_write_cmd_para(0xE4  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x06}; 
        lcd_qspi_write_cmd_para( 0xE5  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0x21}; 
        lcd_qspi_write_cmd_para( 0xE6  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xE7  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x05}; 
        lcd_qspi_write_cmd_para(0xE8  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xF2}; 
        lcd_qspi_write_cmd_para( 0xE9  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xDF}; 
        lcd_qspi_write_cmd_para(0xEA  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x80}; 
        lcd_qspi_write_cmd_para(0xEB  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x26}; 
        lcd_qspi_write_cmd_para(0xEC  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x14}; 
        lcd_qspi_write_cmd_para(0xED  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xFF}; 
        lcd_qspi_write_cmd_para( 0xEE  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xEF  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xFF}; 
        lcd_qspi_write_cmd_para( 0xF8  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xF9  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xFA  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0x30}; 
        lcd_qspi_write_cmd_para(0xFB  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xFC  , data, sizeof(data) );
    }

    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xFD  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xFE  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xFF  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x42}; 
        lcd_qspi_write_cmd_para(0x60  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xE0}; 
        lcd_qspi_write_cmd_para(0x61  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x40}; 
        lcd_qspi_write_cmd_para(0x62  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x40}; 
        lcd_qspi_write_cmd_para( 0x63  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para(0x64  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x65  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x40}; 
        lcd_qspi_write_cmd_para(0x66  , data, sizeof(data) );
    }



	
    {
        uint8_t data[] = {0x03}; 
        lcd_qspi_write_cmd_para(0x67  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x68  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x68  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0x6A  , data, sizeof(data) );
    }

	{
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0x6B  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0x42}; 
        lcd_qspi_write_cmd_para(0x70  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xE0}; 
        lcd_qspi_write_cmd_para(0x71  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x40}; 
        lcd_qspi_write_cmd_para(0x72  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x40}; 
        lcd_qspi_write_cmd_para(0x73  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para(0x74  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x75  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x40}; 
        lcd_qspi_write_cmd_para(0x76  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0x03}; 
        lcd_qspi_write_cmd_para(0x77  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x78  , data, sizeof(data) );
    }

  {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x79  , data, sizeof(data) );
    }
	  {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x7A  , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x7B  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x48}; 
        lcd_qspi_write_cmd_para(0x80  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0x81  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x05}; 
        lcd_qspi_write_cmd_para(0x82  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para(0x83  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xDD}; 
        lcd_qspi_write_cmd_para(0x84  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x85  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x86  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x87  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x48}; 
        lcd_qspi_write_cmd_para(0x88  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x89  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0x07}; 
        lcd_qspi_write_cmd_para(0x8A  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para( 0x8B  , data, sizeof(data) );
    }
	
	 {
        uint8_t data[] = {0xDF}; 
        lcd_qspi_write_cmd_para(0x8C  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x8D  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x8E  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0x8F  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x48}; 
        lcd_qspi_write_cmd_para(0x90  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x91  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x09}; 
        lcd_qspi_write_cmd_para(0x92  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para(0x93  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xE1}; 
        lcd_qspi_write_cmd_para(0x94  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x95  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x96  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x97  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x48}; 
        lcd_qspi_write_cmd_para(0x98  , data, sizeof(data) );
    }

   {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x99  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0B }; 
        lcd_qspi_write_cmd_para(0x9A , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para(0x9B  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xE3}; 
        lcd_qspi_write_cmd_para( 0x9C  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para(0x9D  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para(0x9E  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0x9F  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x48}; 
        lcd_qspi_write_cmd_para( 0xA0  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xA1  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x04}; 
        lcd_qspi_write_cmd_para( 0xA2  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para(0xA3  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0xDC}; 
        lcd_qspi_write_cmd_para( 0xA4  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xA5  , data, sizeof(data) );
    }
	
	 {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xA6  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xA7  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x48}; 
        lcd_qspi_write_cmd_para( 0xA8  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xA9  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x06}; 
        lcd_qspi_write_cmd_para(0xAA  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para(0xAB  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xDE}; 
        lcd_qspi_write_cmd_para(0xAC  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para( 0xAD  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para(0xAE  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xAF  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x48}; 
        lcd_qspi_write_cmd_para(0xB0  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xB1  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x08}; 
        lcd_qspi_write_cmd_para(0xB2  , data, sizeof(data) );
    }

   {
        uint8_t data[] = {0x02 }; 
        lcd_qspi_write_cmd_para(0xB3 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xE0}; 
        lcd_qspi_write_cmd_para(0xB4  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para(0xB5  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para( 0xB6  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para(0xB7  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x48}; 
        lcd_qspi_write_cmd_para(0xB8  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xB9  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0A}; 
        lcd_qspi_write_cmd_para(0xBA  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para(0xBB  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xE2}; 
        lcd_qspi_write_cmd_para(0xBC  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para(0xBD  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para(0xBE  , data, sizeof(data) );
    }
	
	 {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para(0xBF  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x22}; 
        lcd_qspi_write_cmd_para(0xC0  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x98}; 
        lcd_qspi_write_cmd_para(0xC1  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x65}; 
        lcd_qspi_write_cmd_para( 0xC2  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x74}; 
        lcd_qspi_write_cmd_para(0xC3  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x47}; 
        lcd_qspi_write_cmd_para(0xC4  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x56}; 
        lcd_qspi_write_cmd_para( 0xC5  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0}; 
        lcd_qspi_write_cmd_para(0xC6  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xBA}; 
        lcd_qspi_write_cmd_para(0xC7  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xAB}; 
        lcd_qspi_write_cmd_para(0xC8  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x33}; 
        lcd_qspi_write_cmd_para(0xC9  , data, sizeof(data) );
    }
	
    {
        uint8_t data[] = {0x11}; 
        lcd_qspi_write_cmd_para(0xD0  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x98}; 
        lcd_qspi_write_cmd_para(0xD1  , data, sizeof(data) );
    }

   {
        uint8_t data[] = {0x65}; 
        lcd_qspi_write_cmd_para(0xD2  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x74}; 
        lcd_qspi_write_cmd_para(0xD3  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x47}; 
        lcd_qspi_write_cmd_para(0xD4  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x56}; 
        lcd_qspi_write_cmd_para( 0xD5  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x0 }; 
        lcd_qspi_write_cmd_para( 0xD6 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xBA}; 
        lcd_qspi_write_cmd_para(0xD7  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0xAB}; 
        lcd_qspi_write_cmd_para( 0xD8  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x33}; 
        lcd_qspi_write_cmd_para(0xD9  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x01}; 
        lcd_qspi_write_cmd_para( 0xF3  , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para(0xF0  , data, sizeof(data) );
    }
	/*
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0x35  , data, sizeof(data) );
    }
	*/
    {
        uint8_t data[] = {0x55}; 
        lcd_qspi_write_cmd_para(0x3A  , data, sizeof(data) );
    }
	
    {
        lcd_qspi_write_cmd_para( 0x21 , NULL, 0 );
    }  
#else //in order

    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xDE , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x98,0x55};
        lcd_qspi_write_cmd_para( 0xDF , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x1F}; 
        lcd_qspi_write_cmd_para( 0xB2 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x1D,0x00,0x45};
        lcd_qspi_write_cmd_para( 0xB7 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x1B,0x64,0xC4,0x1E,0x3E,0xF5};
        lcd_qspi_write_cmd_para( 0xBB , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x03,0x20,0xF3,0xC0};
        lcd_qspi_write_cmd_para( 0xBC , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x22,0xA1}; 
        lcd_qspi_write_cmd_para( 0xC0 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x02,0x2A,0x0B,0x08,0x48,0x08,0x04,0x62,0x30,0x30}; 
        lcd_qspi_write_cmd_para( 0xC3 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x40,0x00,0xAD,0x68,0x43,0x07,0x04,0x16,0x43,0x07,0x04};
        lcd_qspi_write_cmd_para( 0xC4 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x3F,0x36,0x30,0x2D,0x2F,0x31,0x2B,0x2A,0x27,0x25,0x1F,0x14,0x10,0x09,0x04,0x00,0x3F,0x36,0x30,0x2D,0x2F,0x31,0x2B,0x2A,0x27,0x25,0x1F,0x14,0x10,0x09,0x04,0x00}; 
        lcd_qspi_write_cmd_para( 0xC8 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x28,0x13};
        lcd_qspi_write_cmd_para( 0xD3 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x00,0xFF,0x00,0xF0,0x00}; 
        lcd_qspi_write_cmd_para( 0xD9 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xDE , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x4A,0x80}; 
        lcd_qspi_write_cmd_para( 0xC1 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x16,0xDA,0xE7}; 
        lcd_qspi_write_cmd_para( 0xC2 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x00,0x00,0x38,0x08,0x08,0x00,0x01}; 
        lcd_qspi_write_cmd_para( 0xC7 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x00,0x00,0x00,0x15,0x3B}; 
        lcd_qspi_write_cmd_para( 0xc8 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x16,0x06,0x04,0x0A}; 
        lcd_qspi_write_cmd_para( 0xc9 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x08,0x35,0x16,0x1F,0x1F}; 
        lcd_qspi_write_cmd_para( 0xCA , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x01,0x16,0x07,0x05,0x0B}; 
        lcd_qspi_write_cmd_para( 0xCB , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x09,0x35,0x16,0x1F,0x1F}; 
        lcd_qspi_write_cmd_para( 0xCC , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x01,0x16,0x09,0x0B,0x05}; 
        lcd_qspi_write_cmd_para( 0xCD , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x07,0x15,0x1F,0x16,0x1F}; 
        lcd_qspi_write_cmd_para( 0xCE , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x16,0x08,0x0A,0x04}; 
        lcd_qspi_write_cmd_para( 0xCF , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x06,0x15,0x1F,0x16,0x1F}; 
        lcd_qspi_write_cmd_para( 0xD0 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02,0x30}; 
        lcd_qspi_write_cmd_para( 0xD1 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02,0x03,0x52,0xDF,0xDD}; 
        lcd_qspi_write_cmd_para( 0xD2 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x3B,0x04,0x48}; 
        lcd_qspi_write_cmd_para( 0xD3 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x10,0x10,0x07,0x07,0x0F,0x94,0x26}; 
        lcd_qspi_write_cmd_para( 0xD5 , data, sizeof(data) );
    }
	    
    {
        uint8_t data[] = {0x00,0x00,0x40}; 
        lcd_qspi_write_cmd_para( 0xD6 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x00,0x20}; 
        lcd_qspi_write_cmd_para( 0xD7 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x02}; 
        lcd_qspi_write_cmd_para( 0xDE , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x1C}; 
        lcd_qspi_write_cmd_para( 0xB6 , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0xDE , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0x4D , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0x4E , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0x4F , data, sizeof(data) );
    }
	{
        uint8_t data[] = {0x01}; 
        lcd_qspi_write_cmd_para( 0x4C , data, sizeof(data) );
    }
	LCD_DELAY_MS( 10 );
	{
        uint8_t data[] = {0x00}; 
        lcd_qspi_write_cmd_para( 0x4C , data, sizeof(data) );
    }
	
	{
        lcd_qspi_write_cmd_para( 0x35 , NULL, 0 );
    }
	
    {
        uint8_t data[] = {0x55};
        lcd_qspi_write_cmd_para( 0x3A , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x00,0x01,0x67};
        lcd_qspi_write_cmd_para( 0x2A , data, sizeof(data) );
    }
    {
        uint8_t data[] = {0x00,0x00,0x01,0x67}; 
        lcd_qspi_write_cmd_para( 0x2B , data, sizeof(data) );
    }   
    
#endif
    {
        lcd_qspi_write_cmd_para( 0x11 , NULL, 0 );
    }
    LCD_DELAY_MS( 120 );
    {
        lcd_qspi_write_cmd_para( 0x29 , NULL, 0 );
    }
    LCD_DELAY_MS( 20 );
//	{
//        lcd_qspi_write_cmd_para( 0x1c , NULL, 0 );
//    }
}

#define BIT_RFNE                                (0x00000001 << 3)
#define BIT_ADDR_PHASE_LENGTH(x)                ((x) & 0x00000003)
#define BIT_RD_DUMMY_LENGTH(x)                  (((x) & 0x00000fff))

bool em_lcd_qspi_read(uint16_t addr, uint16_t data_len, uint8_t *data)
{
    uint32_t rd_num = 0;
    SPIC2->ssienr = DISABLE;

    //set addr channel and data channel in ctrl0 register.
    SPIC2->ctrlr0 &= ~(BIT_CMD_CH(3) | BIT_ADDR_CH(3) | BIT_DATA_CH(3));

    //set RX mode in ctrl0 register in user mode.
    SPIC2->ctrlr0 |= BIT_TMOD(3);
    //spic_set_ctrl1(data_len);
    SPIC2->ctrlr1 = data_len;

    SPIC2->addr_length = BIT_ADDR_PHASE_LENGTH(3);
    //set dummy_cycle in autolen register[11:0]
    HAL_UPDATE32(&SPIC2->auto_length, 0xfff, BIT_RD_DUMMY_LENGTH(2));

    addr = addr << 8;
    SPIC2->dr[0].word = 0x03 | __REV(addr);

    SPIC2->ssienr = ENABLE;

    while (rd_num < data_len)
    {
        if (SPIC2->sr & BIT_RFNE)
        {
            data[rd_num++] = SPIC2->dr[0].byte;
        }
    }

    SPIC2->ssienr = DISABLE;

    return true;
}

void em_lcd_qspi_read_test(void)
{
    //Pad_Config(P4_3, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_ENABLE, PAD_OUT_LOW);
    //lcd_qspi_cmd_param(0xFE, 0x00);//page switch
//    {
//        uint8_t data[] = {0x00}; 
//        lcd_qspi_write_cmd_para( 0xfe , data, sizeof(data) );
//    }
//    //lcd_qspi_write_cmd(0xF1);
//    {
//        uint8_t data[] = {0x00}; 
//        lcd_qspi_write_cmd_para( 0xf1 , data, sizeof(data) );
//    }
    uint8_t buf[6],bufda[6],bufdb[6],bufdc[6];
    em_lcd_qspi_read(0x04, 4, buf);
    //DBG_DIRECT("[QSPI READ] %x - %x", buf[0], buf[1]);
    
    em_lcd_qspi_read(0x0a, 2, bufda); // 0xda
    //DBG_DIRECT("[QSPI READ] %x - %x", bufda[0], bufda[1]);
    
    em_lcd_qspi_read(0x10, 2, bufdb);
   // DBG_DIRECT("[QSPI READ] %x - %x", bufdb[0], bufdb[1]);
    
    em_lcd_qspi_read(0x06, 2, bufdc);
    DBG_DIRECT("[QSPI READ] %x - %x", bufdc[0], bufdc[1]);
    //Pad_Config(P4_3, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
    //while (1);
}

void em_lcd_init(void)
{
//    if( !is_initialized )
    {
//        is_initialized = true; 
        lcd_common_init();
        driver_init();
//        em_lcd_qspi_read_test();
//        lcd_qspi_clear(0,0,GUI_LCD_RES_H-1,GUI_LCD_RES_V-1,0x00F8);
    }
}

void em_lcd_power_off(void)
{
    lcd_qspi_write_cmd_para( 0x28 ,NULL,0); // turn off 
    LCD_DELAY_MS( 20 );
    lcd_qspi_write_cmd_para( 0x10 ,NULL,0); // sleep in 
    LCD_DELAY_MS( 20 );
    xDLPS_reset( lcd_dlps_index );
}

//void em_lcd_power_on(void)
//{
//    lcd_gdma_init();
//    lcd_qspi_write_cmd_para( 0x11 ,NULL,0); // sleep out 
//    LCD_DELAY_MS( 120 );
//    lcd_qspi_write_cmd_para( 0x29 ,NULL,0); // turn on 
//    LCD_DELAY_MS( 20 );
//}
void em_lcd_sleep_out(void)
{
    lcd_gdma_init();
    lcd_qspi_write_cmd_para( 0x11 ,NULL,0);
    LCD_DELAY_MS( 120 );
    xDLPS_set( lcd_dlps_index );
}
void em_lcd_turn_on(void)
{
    lcd_qspi_write_cmd_para( 0x29 ,NULL,0);
    LCD_DELAY_MS( 120 );
}
GUI_RAM_CODE
void em_lcd_set_window(int16_t x0, int16_t y0, int16_t w, int16_t h)
{
    uint16_t xstart = x0;
    uint16_t ystart = y0;
    uint16_t xend = xstart + w - 1;
    uint16_t yend = ystart + h - 1;
    uint8_t  data[4];

    data[0] = xstart >> 8;
    data[1] = xstart & 0xff;
    data[2] = xend >> 8;
    data[3] = xend & 0xff;
    lcd_qspi_write_cmd_para(0x2A,data,4);

    data[0] = ystart >> 8;
    data[1] = ystart & 0xff;
    data[2] = yend >> 8;
    data[3] = yend & 0xff;
    lcd_qspi_write_cmd_para(0x2B,data,4);

    lcd_qspi_enter_data_output_mode();
}

GUI_RAM_CODE
void em_lcd_write(uint8_t* p_buffer, uint32_t size)
{   
    if( lcd_wrctl.isbusy )
    {
        return;
    }
    
    lcd_wrctl.isbusy = true; 
    lcd_wrctl.block_write = false;
    lcd_wrctl.pdata = (uint8_t*)p_buffer;
    lcd_wrctl.offset = 0;
    lcd_wrctl.size = size;
    
    uint32_t chunk_remain = size; 
    if( chunk_remain > LCD_XFER_MAX_SIZE )
    {
        chunk_remain = LCD_XFER_MAX_SIZE; 
    }
    lcd_wrctl.offset = chunk_remain;
    LCD_SEND_DATA_ASYNC( lcd_wrctl.pdata, chunk_remain );
}

/*
    p_buffer -> LCD Memory 
    offset   -> next block offset 
    size     -> size of block  
    rows     -> block count 
*/
GUI_RAM_CODE
void em_lcd_write_block( uint8_t* p_buffer, int16_t offset, uint16_t size, int16_t count )
{
    if( lcd_wrctl.isbusy )
    {
        return;
    }
    
    lcd_wrctl.isbusy                = true;
    lcd_wrctl.block_write           = true; 
    lcd_wrctl.pdata                 = (uint8_t*)p_buffer;
    lcd_wrctl.offset                = 0; 
    lcd_wrctl.size                  = size; 
    
    lcd_wrctl.blocks.used           = 0;
    lcd_wrctl.blocks.size           = size;
    lcd_wrctl.blocks.count          = count;
    lcd_wrctl.blocks.offset         = offset;
    
    uint32_t chunk_remain = size; 
    if( chunk_remain > LCD_XFER_MAX_SIZE )
    {
        chunk_remain = LCD_XFER_MAX_SIZE; 
    }
    lcd_wrctl.offset                = chunk_remain; 
    LCD_SEND_DATA_ASYNC( lcd_wrctl.pdata, chunk_remain );
//    LOG_INFO1("[LCD]: block write count = %d", count );
}

void em_lcd_draw_point( int16_t x, int16_t y, uint16_t color )
{
//    em_lcd_set_window(x, y, 1, 1 );
//    LCD_SEND_DATA_ASYNC( (uint8_t*)&color, 2);
    int16_t x0 = x, y0 = y, w = 2, h = 2;
    uint16_t xstart = x0;
    uint16_t ystart = y0;
    uint16_t xend = xstart + w - 1;
    uint16_t yend = ystart + h - 1;
    uint8_t  data[14];

    data[0] = xstart >> 8;
    data[1] = xstart & 0xff;
    data[2] = xend >> 8;
    data[3] = xend & 0xff;
    lcd_qspi_write_cmd_para(0x2A,data,4);

    data[0] = ystart >> 8;
    data[1] = ystart & 0xff;
    data[2] = yend >> 8;
    data[3] = yend & 0xff;
    lcd_qspi_write_cmd_para(0x2B,data,4);

    data[0] = color >> 8;
    data[1] = color & 0xff;
    data[2] = color >> 8;
    data[3] = color & 0xff;
    data[4] = color >> 8;
    data[5] = color & 0xff;
    data[6] = color >> 8;
    data[7] = color & 0xff;
    lcd_qspi_write_cmd_para(0x2C,data,8);
}

void em_lcd_wait_transfer_completed(void)
{
    uint32_t timestamp=em_rtc_get_ticks();
    while( lcd_wrctl.isbusy && !em_rtc_check_time_expired( timestamp, EM_RTC_TOTICKS(500) ));
}

bool em_lcd_check_transfer_completed(void)
{
    return lcd_wrctl.isbusy; 
}


